/*
 * @lc app=leetcode.cn id=529 lang=typescript
 *
 * [529] 扫雷游戏
 */

// @lc code=start
interface Cell {
  x: number;
  y: number;
}

function updateBoard(board: string[][], click: number[]): string[][] {
  // 查找当前位置周围是否有雷，并返回数量
  const findMine = (x: number, y: number, dirs: number[][]): number => {
    let res = 0;
    for (const [dx, dy] of dirs) {
      const nx = x + dx;
      const ny = y + dy;
      if (nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
      if (board[nx][ny] === 'M') res++;
    }
    return res;
  };
  // 如果是雷，修改状态后直接返回
  if (board[click[0]][click[1]] === 'M') {
    board[click[0]][click[1]] = 'X';
    return board;
  }

  const m = board.length;
  const n = board[0].length;
  const dirs = [
    [-1, 0],
    [1, 0],
    [0, -1],
    [0, 1],
    [-1, -1],
    [-1, 1],
    [1, -1],
    [1, 1],
  ];
  const queue: Cell[] = [];
  // 初始化状态
  queue.push({ x: click[0], y: click[1] });
  board[click[0]][click[1]] = 'B';
  // 开始搜索
  while (queue.length) {
    const cur = queue.shift();
    const mines = findMine(cur.x, cur.y, dirs);
    if (mines > 0) {
      board[cur.x][cur.y] = String(mines);
      continue;
    }
    for (const [dx, dy] of dirs) {
      const x = cur.x + dx;
      const y = cur.y + dy;
      if (x < 0 || x >= m) continue;
      if (y < 0 || y >= n) continue;
      if (board[x][y] !== 'E') continue;
      board[x][y] = 'B';
      queue.push({ x, y });
    }
  }

  return board;
}
// @lc code=end
